//
//  3DObjFileMex.c
//  3DImportTest
//
//  Created by David Michaeli on 27/08/12.
//  Email: meexmachina@gmail.com
//  Copyright (c) 2012 David Michaeli. All rights reserved.
//

#include <stdio.h>


#include "3DObjFileMex.h"
#include "3DObjFile.h"

// Define argument count
const int numInputArgs  = 1;
const int numOutputArgs = 2;


void mexFunction(int nlhs,
				 mxArray *plhs[],
				 int nrhs,
				 const mxArray *prhs[])
{
    char *input_filename;
    int status;
    int buflen;
    ObjModel* model = NULL;
    float * vertices = NULL;
    float * faces = NULL;
    unsigned int i = 0;
    
    /* Check for proper number of arguments. */
    if (nrhs != numInputArgs)
        mexErrMsgTxt("One input required.");
    else if (nlhs > numOutputArgs)
        mexErrMsgTxt("Too many output arguments.");
    
    /* Input must be a string. */
    if (mxIsChar(prhs[0]) != 1)
        mexErrMsgTxt("Input must be a string.");
    
    /* Input must be a row vector. */
    if (mxGetM(prhs[0]) != 1)
        mexErrMsgTxt("Input must be a row vector.");
    
    /* Get the length of the input string. */
    buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;
    
    input_filename = mxCalloc(buflen, sizeof(char));
    
    /* Copy the string data from prhs[0] into a C string
     * input_buf. If the string array contains several rows,
     * they are copied, one column at a time, into one long
     * string array. */
    status = mxGetString(prhs[0], input_filename, buflen);
    if (status != 0)
        mexWarnMsgTxt("Not enough space. String is truncated.");
    
    // Open the model file
    model = ObjLoadFile(input_filename);
    if (model == NULL)
    {
        mexErrMsgTxt("Failed to open .obj file - file not found or not enough memory.");
        return;
    }

    // fill the output matrix with the values
    plhs[0] = mxCreateNumericMatrix(model->nVertex, 3, mxSINGLE_CLASS, mxREAL);
    plhs[1] = mxCreateNumericMatrix(model->nTriangle, 3, mxSINGLE_CLASS, mxREAL);
    
    vertices = (float *) mxGetData(plhs[0]);
    faces = (float *) mxGetData(plhs[1]);
        
    // Vertices
    for (i = 0; i<model->nVertex; i++)
    {
        vertices[i+0*model->nVertex] = model->VertexArray[i].x;
        vertices[i+1*model->nVertex] = model->VertexArray[i].y;
        vertices[i+2*model->nVertex] = model->VertexArray[i].z;
    }
    
    // Triangles
    for (i = 0; i<model->nTriangle; i++)
    {
        faces[i+0*model->nTriangle] = model->TriangleArray[i].Vertex[0];
        faces[i+1*model->nTriangle] = model->TriangleArray[i].Vertex[1];
        faces[i+2*model->nTriangle] = model->TriangleArray[i].Vertex[2];
    }
    
    // cleanup the model memory
    ObjFreeModel (model);
    
};
